import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useEffect } from 'react';
import { apiClient, type CreatePostRequest } from '../lib/api';
import { usePostActions } from '../store/useStore';
import toast from 'react-hot-toast';

// Query Keys
export const queryKeys = {
  users: ['users'] as const,
  user: (id: number) => ['users', id] as const,
  posts: ['posts'] as const,
  post: (id: number) => ['posts', id] as const,
  userPosts: (userId: number) => ['posts', 'user', userId] as const,
};

// Users Queries
export const useUsersQuery = () => {
  return useQuery({
    queryKey: queryKeys.users,
    queryFn: () => apiClient.getUsers(),
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
};

export const useUserQuery = (id: number) => {
  return useQuery({
    queryKey: queryKeys.user(id),
    queryFn: () => apiClient.getUser(id),
    enabled: !!id,
    staleTime: 5 * 60 * 1000,
  });
};

// Posts Queries
export const usePostsQuery = () => {
  const { setPosts } = usePostActions();
  
  const query = useQuery({
    queryKey: queryKeys.posts,
    queryFn: () => apiClient.getPosts(),
    staleTime: 2 * 60 * 1000, // 2 minutes
  });

  // Sync data with Zustand store when it changes
  useEffect(() => {
    if (query.data) {
      setPosts(query.data);
    }
  }, [query.data, setPosts]);

  return query;
};

export const usePostQuery = (id: number) => {
  return useQuery({
    queryKey: queryKeys.post(id),
    queryFn: () => apiClient.getPost(id),
    enabled: !!id,
  });
};

export const useUserPostsQuery = (userId: number) => {
  return useQuery({
    queryKey: queryKeys.userPosts(userId),
    queryFn: () => apiClient.getUserPosts(userId),
    enabled: !!userId,
  });
};

// Posts Mutations
export const useCreatePostMutation = () => {
  const queryClient = useQueryClient();
  const { addPost } = usePostActions();

  return useMutation({
    mutationFn: (data: CreatePostRequest) => apiClient.createPost(data),
    onSuccess: (newPost) => {
      // Update the cache
      queryClient.invalidateQueries({ queryKey: queryKeys.posts });
      queryClient.invalidateQueries({ 
        queryKey: queryKeys.userPosts(newPost.userId) 
      });
      
      // Update Zustand store
      addPost(newPost);
      
      toast.success('Post created successfully!');
    },
    onError: (error) => {
      toast.error(`Failed to create post: ${error.message}`);
    },
  });
};

export const useUpdatePostMutation = () => {
  const queryClient = useQueryClient();
  const { updatePost } = usePostActions();

  return useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<CreatePostRequest> }) =>
      apiClient.updatePost(id, data),
    onSuccess: (updatedPost) => {
      // Update specific post in cache
      queryClient.setQueryData(
        queryKeys.post(updatedPost.id),
        updatedPost
      );
      
      // Invalidate related queries
      queryClient.invalidateQueries({ queryKey: queryKeys.posts });
      queryClient.invalidateQueries({ 
        queryKey: queryKeys.userPosts(updatedPost.userId) 
      });
      
      // Update Zustand store
      updatePost(updatedPost.id, updatedPost);
      
      toast.success('Post updated successfully!');
    },
    onError: (error) => {
      toast.error(`Failed to update post: ${error.message}`);
    },
  });
};

export const useDeletePostMutation = () => {
  const queryClient = useQueryClient();
  const { deletePost } = usePostActions();

  return useMutation({
    mutationFn: (id: number) => apiClient.deletePost(id),
    onSuccess: (_, deletedId) => {
      // Remove from cache
      queryClient.removeQueries({ queryKey: queryKeys.post(deletedId) });
      queryClient.invalidateQueries({ queryKey: queryKeys.posts });
      
      // Update Zustand store
      deletePost(deletedId);
      
      toast.success('Post deleted successfully!');
    },
    onError: (error) => {
      toast.error(`Failed to delete post: ${error.message}`);
    },
  });
};

// Prefetch utilities
export const usePrefetchPost = () => {
  const queryClient = useQueryClient();

  return (id: number) => {
    queryClient.prefetchQuery({
      queryKey: queryKeys.post(id),
      queryFn: () => apiClient.getPost(id),
      staleTime: 5 * 60 * 1000,
    });
  };
};

export const usePrefetchUser = () => {
  const queryClient = useQueryClient();

  return (id: number) => {
    queryClient.prefetchQuery({
      queryKey: queryKeys.user(id),
      queryFn: () => apiClient.getUser(id),
      staleTime: 5 * 60 * 1000,
    });
  };
}; 